package com.scvtc.utils;

import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.scvtc.annotation.like.LikeIgnore;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;

/**
 * @Description: 模糊查询工具类
 * @Author: yiFei
 * @date: 2022/5/23 14:50
 */
public class LikeQueryUtil {

    private LikeQueryUtil() {
    }

    public static final Boolean FLAG = true;

    /**
     * 模糊查询封装 (QueryWrapper)
     *
     * @param obj       有数据的模糊查询字段
     * @param realClass 需要返回的实体类  QueryWrapper< realClass >
     * @param <T>
     * @param <O>
     * @return
     */
    public static <T, O> QueryWrapper<T> likeQuery(O obj, Class<T> realClass) {
        // 创建 QueryWrapper
        QueryWrapper<T> likeQueryWrapper = new QueryWrapper<>();
        // 需要模糊查询的类

        Field[] likeFields = obj.getClass().getDeclaredFields();
        Field[] realFields = realClass.getDeclaredFields();

        /* 匹配字段名字 */
        for (Field likeField : likeFields) {
            try {
                // 打破封装
                likeField.setAccessible(true);
                // 判断是否忽略
                if (ignore(obj, likeField)) continue;
                // 判断是否匹配
                for (Field realField : realFields) {
                    if (likeField.getName().equals(realField.getName())) {
                        // 已经过滤不是 String 类型数据
                        String string = (String) likeField.get(obj);
                        likeQueryWrapper.like(StringUtils.hasText(string), convert(likeField.getName()), string);
                    }
                }
            } catch (IllegalAccessException e) {
                e.getStackTrace();
            }
        }
        return likeQueryWrapper;
    }

    /**
     * 判断是否忽略
     *
     * @param obj
     * @param likeField
     * @return
     * @throws IllegalAccessException
     */
    private static boolean ignore(Object obj, Field likeField) throws IllegalAccessException {
        // 默认认为不是 String 的不会被模糊查询
        return likeField.get(obj) == null ||
                likeField.getType() != String.class ||
                "serialVersionUID".equals(likeField.getName()) ||
                "id".equals(likeField.getName().toLowerCase()) ||
                likeField.isAnnotationPresent(TableId.class) ||
                likeField.isAnnotationPresent(LikeIgnore.class);
    }

    /**
     * 将字段转换为数据库字段
     *
     * @return
     */
    private static String convert(String fieldName) {
        // 查看是否需要转换
        if (FLAG) {
            // 我认为一般字段就20的长度
            StringBuilder stringBuffer = new StringBuilder(20);
            // 循环遍历查看是否有大写字段
            for (int i = 0; i < fieldName.length(); i++) {
                // 获取字符
                char word = fieldName.charAt(i);
                if ('A' <= word && word <= 'Z') {
                    // 拼接一个下划线 , 然后 -32 变成小写字母
                    stringBuffer.append('_');
                    stringBuffer.append((char) (word + 32));
                } else {
                    stringBuffer.append(word);
                }
            }
            return stringBuffer.toString();
        }
        return fieldName;
    }

}
